package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
@PropertySource(value = "classpath:/properties/image.properties",encoding = "UTF-8")//配置文件中可以有中文
public class FileServiceImpl implements FileService{

    private static Set<String> typeSet = new HashSet<>();
    static {//为静态属性赋值
        //利用配置文件动态将图片类型获取
        typeSet.add(".jpg");
        typeSet.add(".png");
        typeSet.add(".gif");
    }
    @Value("${image.fileDir}")
    private  String fileDir;    //  C:/images
    @Value("${image.urlPath}")
    private String urlPath;     //  设置域名地址
    /**
     * 核心业务逻辑:实现文件上传
     * 步骤:
     *      1.校验图片的类型 jpg/png/gif..
     *      2.校验文件是否为恶意程序...
     *      3.采用分目录的结构进行存储
     *      4.避免文件重名 uuid
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
    //1.校验图片的类型 jpg/png/gif..  1)利用集合校验 2)正则表达式
        //1.1获取文件名  qwer.jpg
        String fileName=uploadFile.getOriginalFilename();
        fileName=fileName.toLowerCase();//小写
        //1.2获取文件后缀类型
        String fileType = fileName.substring(fileName.lastIndexOf("."));//.jpg
                        //fileName.split(".");
        //1.3判断是否为图片的类型
        if(!typeSet.contains(fileType)){
            return ImageVO.fail();
        }
    //2.如果是图片 高度/宽度
        //2.1将数据转化为图片对象
        try {
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width==0 || height==0){
                return ImageVO.fail();
            }else {
    //3.实现分目录存储
                //3.1按照年月日进行目录划分            //hashCode();//8位 16进制数字  1&2位为一级
                String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
                //"C:/images/2020/12/1/";
                String fileDirPath = fileDir+dateDir;
                File dirFile = new File(fileDirPath);
                if(!dirFile.exists()){
                    dirFile.mkdirs();
                }
    //4.实现文件的上传
                //4.1准备文件的名称 uuid
                String uuid= UUID.randomUUID().toString().replace("-", "");
                //4.2动态生成文件的名称
                String uuidName = uuid+fileType;
                //4.3实现文件的上传
                File realFile = new File(fileDirPath+uuidName);
                uploadFile.transferTo(realFile);

                //网络地址和本地地址根目录都不会发生变化(时间目录之前的部分),
                //本地地址   "C:/images/"+"2020/12/1/a.jpg"
                //网络地址   "http://image.jt.com/"+"2020/12/1/a.jpg"
                String url = urlPath+dateDir+uuidName;
                return ImageVO.success(url, width, height);

            }
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail();//报错返回
        }
    }
}
